/*********************************************************************************
 *      Copyright:  (C) 2022 Zhang xiangyun<1327295677@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  server.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(03/05/22)
 *         Author:  Zhang xiangyun <1327295677@qq.com>
 *      ChangeLog:  1, Release initial version on "03/05/22 16:02:50"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <sys/epoll.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "logger.h"

void set_socket_rlimit(void);
int socket_server_init(char *listen_ip, int listen_port);

void set_socket_rlimit(void)
{
	struct rlimit limit ={0};
	getrlimit(RLIMIT_NOFILE,&limit);
	limit.rlim_cur = limit.rlim_max;
	setrlimit(RLIMIT_NOFILE,&limit);
	printf("set socket oprn fd max count to %d\n",limit.rlim_max);
}

int socket_server_init(char *listen_ip, int listen_port)
{
	struct sockaddr_in             servaddr;
	int                            rv=0;
	int                            on=1;
	int                            listen_fd=-1;

	if((listen_fd=socket(AF_INET,SOCK_STREAM,0))<0)
	{
		log_error("use socket() to create a TCP socket failure: %s\n",strerror(errno));
		return -1;
	}

	/* set socket port can reuse */
	setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(listen_port);

	if(!listen_ip)
	{
		servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
	}
	else 
	{
		if(inet_pton(AF_INET,listen_ip,&servaddr.sin_addr)<=0)
		{
			log_error("inet_pton() set ip address of listen_ip failure:%s",strerror(errno));
			rv=-2;
			goto CleanUp;
		}
	}
	if(bind(listen_fd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0)
	{
		log_error("use bind() to bind the TCP socket failure:%s\n",strerror(errno));
		rv=-3;
		goto CleanUp;
	}
	
	if(listen(listen_fd,64)<0)
	{
		log_error("listen()failure:%s\n",strerror(errno));
		rv=-4;
		goto CleanUp;
	}

CleanUp:
	if(rv<0)
	{
		close(listen_fd);
	}
	else
		rv=listen_fd;
	return rv;
}
